package com.theme.passport.controller.app;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.google.gson.JsonArray;
import com.google.gson.JsonObject;
import com.theme.common.base.JSONHandler;
import com.theme.common.base.http.HttpHandler;
import com.theme.common.mvc.utils.PageUtils;
import com.theme.common.mvc.view.R;
import com.theme.passport.controller.oss.cloud.OSSFactory;
import com.theme.passport.controller.request.param.HotWordVo;
import com.theme.passport.controller.sys.AbstractController;
import com.theme.passport.dao.CustomMapper;
import com.theme.passport.entity.SysUserEntity;
import com.theme.passport.entity.constant.AppStatusEnum;
import com.theme.passport.entity.constant.ThemeAttchmentTypeEnum;
import com.theme.passport.entity.constant.ThemeStatusEnum;
import com.theme.passport.entity.constant.WidgeSizeEnum;
import com.theme.passport.entity.theme.*;
import com.theme.passport.service.SysUserService;
import com.theme.passport.service.theme.*;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.apache.commons.httpclient.NameValuePair;
import org.apache.commons.io.FilenameUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.ZSetOperations;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import java.net.URL;
import java.net.URLEncoder;
import java.util.*;
import java.util.concurrent.TimeUnit;


@RestController
@RequestMapping("app/theme")
@Api("主题管理相关接口")
public class ThemesController extends AbstractController {
    @Autowired
    private ThemeService themeService;

    @Autowired
    private SysUserService sysUserService;

    @Autowired
    private ThemeClassifyService themeClassifyService;

    @Autowired
    private AppIconService appIconService;

    @Autowired
    private ThemeAttachmentService attachmentService;

    @Autowired
    private WidgeService widgeService;

    @Autowired
    private WidgeConfigService widgeConfigService;

    @Autowired
    private RedisTemplate redisTemplate;

    @Autowired
    private CustomMapper mapper;


    @Value("${theme.aliyundir}")
    private String aliyundir;

    @GetMapping("classify")
    @ApiOperation("获取主题分类接口")
    public R classify(@RequestParam(value = "keyword", required = false) String keyword,
                      @RequestParam(value = "page", defaultValue = "1") String page,
                      @RequestParam(value = "limit", defaultValue = "10") String limit) {
        Map<String, Object> params = new HashMap<>();
        params.put("key", keyword);
        params.put("page", page);
        params.put("limit", limit);
        PageUtils pages = themeClassifyService.queryPage(params);
        return R.ok().put("page", pages);
    }

    @GetMapping("list")
    @ApiOperation("查询列表接口")
    public R list(@RequestParam(value = "keyword", required = false) String keyword,
                  @RequestParam(value = "classifyId", required = false) String classifyId,
                  @RequestParam(value = "free", required = false) String free,
                  @RequestParam(value = "page", defaultValue = "1") String page,
                  @RequestParam(value = "limit", defaultValue = "10") String limit) {
        Integer status = ThemeStatusEnum.NORMAL.getValue();
        Map<String, Object> params = new HashMap<>();
        params.put("status", String.valueOf(status));
        params.put("key", keyword);
        params.put("free", free);
        params.put("classifyId", classifyId);
        params.put("page", page);
        params.put("limit", limit);
        PageUtils pages = themeService.queryPage(params);
        List<ThemeEntity> list = (List<ThemeEntity>) pages.getList();
        list.forEach(theme ->{
            //SysUserEntity byId = sysUserService.getById(theme.getUserId());
            //theme.setUseNickname(byId.getNickname());
            //主题标签
            String label = theme.getLabel();
            if (label != null){
                String[] split = label.split(",");
                theme.setLabels(Arrays.asList(split));
            }

            //主题预览图：
            QueryWrapper<ThemeAttachmentEntity> fileNameWrapper = new QueryWrapper<>();
            fileNameWrapper.and(wrapper -> wrapper
                    .eq("type", ThemeAttchmentTypeEnum.THEME.getValue())
                    .eq("object_id", theme.getId()));
            List<ThemeAttachmentEntity> attachmentList = attachmentService.list(fileNameWrapper);
            List<String> images = new ArrayList<>();
            attachmentList.forEach(attachment -> {
                images.add(attachment.getFileUrl());
            });
            theme.setImages(images);
            theme.setXzl(  mapper.getOneInteger("select count(id) from tab_download_history where object_id  = "+theme.getId()+" and  type = 1"));
        });
        pages.setList(list);
        return R.ok().put("page", pages);
    }

    @GetMapping("featured")
    @ApiOperation("查询精选|福利主题接口[free表示1收费0免费]")
    public R featured(@RequestParam(value = "keyword", required = false) String keyword,
                  @RequestParam(value = "classifyId", required = false) String classifyId,
                  @RequestParam(value = "free",  defaultValue = "1") String free,
                  @RequestParam(value = "page", defaultValue = "1") String page,
                  @RequestParam(value = "limit", defaultValue = "10") String limit) {
        return this.list(keyword, classifyId, free, page, limit);
    }

    @GetMapping("/info")
    @ApiOperation("查询主题详情")
    public R info(@RequestParam("themeId") Long themeId,
                  @RequestParam("version") Integer version) throws Exception {
        ThemeEntity theme = themeService.getById(themeId);
        if(theme == null){
            return R.error("该主题不存在或已下架!!!");
        }
        if (!theme.getStatus().equals(ThemeStatusEnum.NORMAL.getValue())) {
            return R.error("该主题不存在或已下架!!!").put("theme", theme);
        }
        SysUserEntity byId = sysUserService.getById(theme.getUserId());
        if (byId != null){
            theme.setUseNickname(byId.getNickname());
        }

        //获取主题附件名称
        String fileName = theme.getFileName();
        //文件前缀 示列:幸福的夏季.zip 返回：幸福的夏季
        String prefix = fileName.substring(0, fileName.length()-4) +"";
        //文件后缀 示列:幸福的夏季.zip 返回：.zip
        String suffix = fileName.substring(fileName.lastIndexOf("."));
        //阿里云文件存储目录
        String aliyunFileDir = aliyundir+"/"+prefix+"/"+prefix+"/";
        List<String> fileList = OSSFactory.build(null).getFileList(aliyunFileDir, suffix);
        List<AppIconEntity> appIconList = new ArrayList<>();
        for(int i=0;i<fileList.size() ;i++){
            String icon = fileList.get(i);
            URL url = new URL(icon);
            //URL url = new URL("http://www.example.com/some/path/to/a/file.xml");
            //System.out.println(FilenameUtils.getBaseName(url.getPath())); // -> file
            //System.out.println(FilenameUtils.getExtension(url.getPath())); // -> xml
            //System.out.println(FilenameUtils.getName(url.getPath())); // -> file.xml
            // 获取app名称
            String appName = FilenameUtils.getBaseName(url.getPath());
            AppIconEntity appIconEntity = appIconService.getByName(appName);
            if (appIconEntity == null){
                //return R.error("数据库中AppIcon的配置文件不足,请检查["+appName+"]应用是否存在图标的bundleId!");
                // 从苹果官网获取: icon bundleId name 如果在获取不到直接返回错误信息 有的话添加数据库
                Map<String, Object> appleMap = getBundleIdByApple(appName);
                if (appleMap == null){
                    return R.error("获取应用["+appName+"]的配置文件信息bundleId获取失败,请检查["+appName+"]应用图标是否错误!");
                }
                String bundleId = appleMap.get("bundleId").toString();
                String thumb = appleMap.get("thumb").toString();
                //保存存入数据库中
                appIconEntity = new AppIconEntity();
                appIconEntity.setName(appName);
                appIconEntity.setOrigin(appName);
                appIconEntity.setUrl("请手工修正");
                appIconEntity.setBundleId(bundleId);
                String bundleIdUrl = bundleId + "://";
                appIconEntity.setUrl(bundleIdUrl);
                appIconEntity.setThumb(thumb);
                appIconEntity.setCreated(new Date());
                appIconEntity.setStatus(AppStatusEnum.NOT.getValue());

                appIconService.save(appIconEntity);

                appIconEntity.setIcon(icon);
                appIconList.add(appIconEntity);
                continue;
            }
            if (version == 1) {
                appIconEntity.setIcon(icon);
                appIconList.add(appIconEntity);
            }
            if (version == 2) {
                if (!appIconEntity.getStatus().equals(AppStatusEnum.ARE.getValue())){
                    appIconEntity.setIcon(icon);
                    appIconList.add(appIconEntity);
                }
            }
        }
        theme.setAppIconList(appIconList);
        //主题标签
        String label = theme.getLabel();
        if (label != null){
            String[] split = label.split(",");
            theme.setLabels(Arrays.asList(split));
        }
        //主题预览图：
        QueryWrapper<ThemeAttachmentEntity> fileNameWrapper = new QueryWrapper<>();
        fileNameWrapper.and(wrapper -> wrapper
                .eq("type", ThemeAttchmentTypeEnum.THEME.getValue())
                .eq("object_id", theme.getId()));
        List<ThemeAttachmentEntity> attachmentList = attachmentService.list(fileNameWrapper);
        List<String> images = new ArrayList<>();
        attachmentList.forEach(attachment -> {
            images.add(attachment.getFileUrl());
        });
        theme.setImages(images);
        theme.setXzl(  mapper.getOneInteger("select count(id) from tab_download_history where object_id  = "+theme.getId()+" and  type = 1"));
        //获取主题组件列表
        List<WidgeEntity> widgeSizeList = widgeService.queryWidgeList(theme.getId());
        if (widgeSizeList != null && widgeSizeList.size() >0){
            widgeSizeList.sort(Comparator.comparing(WidgeEntity::getId));
            //安装小中大小中大排序-组1
            List<WidgeEntity> widgeSizeListTemp1 = getWidgeSizeList(widgeSizeList);
            if(widgeSizeListTemp1 != null && widgeSizeListTemp1.size() >0){
                theme.setWidgeSizeList(widgeSizeListTemp1);
            }
            widgeSizeListTemp1.forEach(item -> {
                //获取组件配置
                List<WidgeConfigEntity> widgeConfigList = widgeConfigService.queryWidgeConfigList(item.getId());
                item.setWidgeConfigList(widgeConfigList);
            });

            //安装小中大小中大排序-组2
            List<WidgeEntity> widgeSizeListTemp2 = getWidgeSizeList1(widgeSizeList);
            if(widgeSizeListTemp2 != null && widgeSizeListTemp2.size() >0){
                theme.setWidgeSizeList1(widgeSizeListTemp2);
            }
            widgeSizeListTemp2.forEach(item -> {
                //获取组件配置
                List<WidgeConfigEntity> widgeConfigList = widgeConfigService.queryWidgeConfigList(item.getId());
                item.setWidgeConfigList(widgeConfigList);
            });

            //安装小中大小中大排序-组3
            List<WidgeEntity> widgeSizeListTemp3 = getWidgeSizeList2(widgeSizeList);
            if(widgeSizeListTemp3 != null && widgeSizeListTemp3.size() >0){
                theme.setWidgeSizeList2(widgeSizeListTemp3);
            }
            widgeSizeListTemp3.forEach(item -> {
                //获取组件配置
                List<WidgeConfigEntity> widgeConfigList = widgeConfigService.queryWidgeConfigList(item.getId());
                item.setWidgeConfigList(widgeConfigList);
            });

            //安装小中大小中大排序-组4
            List<WidgeEntity> widgeSizeListTemp4 = getWidgeSizeList3(widgeSizeList);
            if(widgeSizeListTemp4 != null && widgeSizeListTemp4.size() >0){
                theme.setWidgeSizeList3(widgeSizeListTemp4);
            }
            widgeSizeListTemp4.forEach(item -> {
                //获取组件配置
                List<WidgeConfigEntity> widgeConfigList = widgeConfigService.queryWidgeConfigList(item.getId());
                item.setWidgeConfigList(widgeConfigList);
            });

        }
        return R.ok().put("theme", theme);
    }

    public Map<String,Object> getBundleIdByApple(String appName) throws Exception {
        List<NameValuePair> nameValuePairList = new ArrayList<>();
        NameValuePair nameValuePair = new NameValuePair();
        nameValuePair.setName("country");
        nameValuePair.setValue("cn");
        nameValuePairList.add(nameValuePair);

        NameValuePair nameValuePaiEntity = new NameValuePair();
        nameValuePaiEntity.setName("entity");
        nameValuePaiEntity.setValue("software");
        nameValuePairList.add(nameValuePaiEntity);

        NameValuePair nameValuePaiLimit = new NameValuePair();
        nameValuePaiLimit.setName("limit");
        nameValuePaiLimit.setValue("1");
        nameValuePairList.add(nameValuePaiLimit);

        NameValuePair nameValuePairTerm = new NameValuePair();
        nameValuePairTerm.setName("term");
        nameValuePairTerm.setValue(URLEncoder.encode(appName, "UTF-8"));
        nameValuePairList.add(nameValuePairTerm);
        String url = "https://itunes.apple.com/search";
        String result = HttpHandler.httpGet(url,nameValuePairList);

        JsonObject jsonObject = JSONHandler.getObjectByJsonStr(result,JsonObject.class);
        int resultCount = jsonObject.get("resultCount").getAsInt();
        if (resultCount != 1){
            return null;
        }
        JsonArray jsonArray = (JsonArray) jsonObject.get("results");
        for (int i = 0; i < jsonArray.size(); i++) {
            JsonObject asJsonObject = jsonArray.get(i).getAsJsonObject();
            String bundleId = asJsonObject.get("bundleId").getAsString();
            String thumb = asJsonObject.get("artworkUrl60").getAsString();
            Map<String,Object> resultMap = new HashMap<>();
            resultMap.put("bundleId",bundleId);
            resultMap.put("thumb",thumb);
            return resultMap;
        }
        return null;
    }


    /**
     * 小中大小中大排序
     * @param widgeSizeList
     */
    public List<WidgeEntity>  getWidgeSizeList(List<WidgeEntity> widgeSizeList){
        List<WidgeEntity> sizeList = new ArrayList<>();
        WidgeEntity widgeSize1 = null;
        WidgeEntity widgeSize2 = null;
        WidgeEntity widgeSize3 = null;
        WidgeEntity widgeSize11 = null;
        WidgeEntity widgeSize22 = null;
        WidgeEntity widgeSize33 = null;
        WidgeEntity widgeSize111 = null;
        WidgeEntity widgeSize1111 = null;
        for (int i = 0; i < widgeSizeList.size(); i++) {
            WidgeEntity widgeSizeEntity = widgeSizeList.get(i);
            if(widgeSizeEntity.getTypeId().equals(new Long(8))){
                //回填天气部分
                List<String> weatherImages = new ArrayList<>();
                //主题预览图：
                LambdaQueryWrapper<ThemeAttachmentEntity> fileNameWrapper = new LambdaQueryWrapper<>();
                fileNameWrapper.eq(ThemeAttachmentEntity::getType, 2)
                        .eq(ThemeAttachmentEntity::getObjectId, widgeSizeEntity.getId());
                List<ThemeAttachmentEntity> attachmentList = attachmentService.list(fileNameWrapper);
                attachmentList.forEach(attachment -> {
                    weatherImages.add(attachment.getFileUrl());
                });
                widgeSizeEntity.setWeatherImages(weatherImages);
            }
            if (widgeSizeEntity.getWidgetSize().equals(WidgeSizeEnum.SMALL.getValue())){
                if (widgeSize1 == null){
                    widgeSize1 = widgeSizeEntity;
                    continue;
                }
                if (widgeSize11 == null){
                    widgeSize11 = widgeSizeEntity;
                    continue;
                }
                if (widgeSize111 == null){
                    widgeSize111 = widgeSizeEntity;
                    continue;
                }
                widgeSize1111 = widgeSizeEntity;
            }
            if (widgeSizeEntity.getWidgetSize().equals(WidgeSizeEnum.MEDIUM.getValue())){
                if (widgeSize2 == null){
                    widgeSize2 = widgeSizeEntity;
                    continue;
                }
                widgeSize22 = widgeSizeEntity;
            }
            if (widgeSizeEntity.getWidgetSize().equals(WidgeSizeEnum.LAREGE.getValue())){
                if (widgeSize3 == null){
                    widgeSize3 = widgeSizeEntity;
                    continue;
                }
                widgeSize33 = widgeSizeEntity;
            }
        }
        if (widgeSize1 != null)sizeList.add(widgeSize1);
        if (widgeSize2 != null)sizeList.add(widgeSize2);
        if (widgeSize3 != null)sizeList.add(widgeSize3);

        return sizeList;
    }

    /**
     * 小中大小中大排序
     * @param widgeSizeList
     */
    public List<WidgeEntity>  getWidgeSizeList1(List<WidgeEntity> widgeSizeList){
        List<WidgeEntity> sizeList = new ArrayList<>();
        WidgeEntity widgeSize1 = null;
        WidgeEntity widgeSize2 = null;
        WidgeEntity widgeSize3 = null;
        WidgeEntity widgeSize11 = null;
        WidgeEntity widgeSize22 = null;
        WidgeEntity widgeSize33 = null;
        WidgeEntity widgeSize111 = null;
        WidgeEntity widgeSize1111 = null;
        for (int i = 0; i < widgeSizeList.size(); i++) {
            WidgeEntity widgeSizeEntity = widgeSizeList.get(i);
            if (widgeSizeEntity.getWidgetSize().equals(WidgeSizeEnum.SMALL.getValue())){
                if (widgeSize1 == null){
                    widgeSize1 = widgeSizeEntity;
                    continue;
                }
                if (widgeSize11 == null){
                    widgeSize11 = widgeSizeEntity;
                    continue;
                }
                if (widgeSize111 == null){
                    widgeSize111 = widgeSizeEntity;
                    continue;
                }
                widgeSize1111 = widgeSizeEntity;
            }
            if (widgeSizeEntity.getWidgetSize().equals(WidgeSizeEnum.MEDIUM.getValue())){
                if (widgeSize2 == null){
                    widgeSize2 = widgeSizeEntity;
                    continue;
                }
                widgeSize22 = widgeSizeEntity;
            }
            if (widgeSizeEntity.getWidgetSize().equals(WidgeSizeEnum.LAREGE.getValue())){
                if (widgeSize3 == null){
                    widgeSize3 = widgeSizeEntity;
                    continue;
                }
                widgeSize33 = widgeSizeEntity;
            }
        }
        if (widgeSize11 != null)sizeList.add(widgeSize11);
        if (widgeSize22 != null)sizeList.add(widgeSize22);
        if (widgeSize33 != null)sizeList.add(widgeSize33);

        return sizeList;
    }

    /**
     * 小中大小中大排序
     * @param widgeSizeList
     */
    public List<WidgeEntity>  getWidgeSizeList2(List<WidgeEntity> widgeSizeList){
        List<WidgeEntity> sizeList = new ArrayList<>();
        WidgeEntity widgeSize1 = null;
        WidgeEntity widgeSize11 = null;
        WidgeEntity widgeSize111 = null;
        WidgeEntity widgeSize1111 = null;
        for (int i = 0; i < widgeSizeList.size(); i++) {
            WidgeEntity widgeSizeEntity = widgeSizeList.get(i);
            if (widgeSizeEntity.getWidgetSize().equals(WidgeSizeEnum.SMALL.getValue())){
                if (widgeSize1 == null){
                    widgeSize1 = widgeSizeEntity;
                    continue;
                }
                if (widgeSize11 == null){
                    widgeSize11 = widgeSizeEntity;
                    continue;
                }
                if (widgeSize111 == null){
                    widgeSize111 = widgeSizeEntity;
                    continue;
                }
                widgeSize1111 = widgeSizeEntity;
            }
        }
        if (widgeSize111 != null)sizeList.add(widgeSize111);
        return sizeList;
    }

    /**
     * 小中大小中大排序
     * @param widgeSizeList
     */
    public List<WidgeEntity>  getWidgeSizeList3(List<WidgeEntity> widgeSizeList){
        List<WidgeEntity> sizeList = new ArrayList<>();
        WidgeEntity widgeSize1 = null;
        WidgeEntity widgeSize11 = null;
        WidgeEntity widgeSize111 = null;
        WidgeEntity widgeSize1111 = null;
        for (int i = 0; i < widgeSizeList.size(); i++) {
            WidgeEntity widgeSizeEntity = widgeSizeList.get(i);
            if (widgeSizeEntity.getWidgetSize().equals(WidgeSizeEnum.SMALL.getValue())){
                if (widgeSize1 == null){
                    widgeSize1 = widgeSizeEntity;
                    continue;
                }
                if (widgeSize11 == null){
                    widgeSize11 = widgeSizeEntity;
                    continue;
                }
                if (widgeSize111 == null){
                    widgeSize111 = widgeSizeEntity;
                    continue;
                }
                widgeSize1111 = widgeSizeEntity;
            }
        }
        if (widgeSize1111 != null)sizeList.add(widgeSize1111);
        return sizeList;
    }

    /**
     * 设置缓存失效时间，统一为凌晨零点
     * @param hotWord
     * @throws Exception
     */
    public  void addHotWord(String hotWord) throws Exception {
        Calendar calendar = Calendar.getInstance();
        calendar.add(Calendar.DAY_OF_YEAR,1);
        calendar.set(Calendar.HOUR_OF_DAY,0);
        calendar.set(Calendar.SECOND,0);
        calendar.set(Calendar.MINUTE,0);
        calendar.set(Calendar.MILLISECOND,0);
        //晚上十二点与当前时间的毫秒差
        Long timeOut = (calendar.getTimeInMillis()-System.currentTimeMillis()) / 1000;
        redisTemplate.expire("hotWord",timeOut, TimeUnit.SECONDS);
        redisTemplate.opsForZSet().incrementScore("hotWord", hotWord, 1);
    }

    /**
     * 获取热词前topnum位
     * @return
     */
    public List<HotWordVo> getHotWord(int topnum) {
        List<HotWordVo> hotWordList = new ArrayList<>();
        Set<ZSetOperations.TypedTuple<Object>> typedTupleSet = redisTemplate.opsForZSet().reverseRangeByScoreWithScores("hotWord",1,100);
        Iterator<ZSetOperations.TypedTuple<Object>> iterator = typedTupleSet.iterator();
        int flag = 0;
        while (iterator.hasNext()){
            flag++;
            ZSetOperations.TypedTuple<Object> typedTuple = iterator.next();
            String value = (String)typedTuple.getValue();
            int score = (int) Math.ceil(typedTuple.getScore());
            HotWordVo hotWord = new HotWordVo(value,score);
            hotWordList.add(hotWord);
            if ( flag >= topnum ) {break;}
        }
        return hotWordList;
    }

}
